<template>
  <div style="padding: 20px 0;" v-loading="loading">
    <div class="common-biz-filter">
      <filterForm ref="filter" @query="onQuery" />
    </div>
    <div class="common-biz-tool">
      <div>
        <el-button v-for="i in actions" v-bind="i" @click="actionHandle(i)">{{ i.label }}</el-button>
      </div>
      <tableOption ref="setting" :refList="$refs" @change="handlerOptionChange" />
    </div>
    <div class="common-biz-body">
      <configTable :data="list" v-bind="table" @tableEvent="tableEvent" @column-width-change="colunmWidthChange" />
    </div>
    <div class="common-biz-pagnation" v-if="pagination">
      <el-pagination v-bind="pagination" @current-change="pageNoChange"
        @size-change="pageSizeChange" />
    </div>
    <dialogForm ref="form" @submit="onSubmit" />
  </div>
</template>
<script>
import axios from 'axios';
import bus from '@/utils/bus'
import http, { request } from '@/utils/request'
import filterForm from './components/filterForm'
import dialogForm from './components/dialogForm'
import tableOption from './components/tableOption'
import configTable from './components/configTable'
export default {
  name: 'CommonBiz',
  components: {
    filterForm,
    configTable,
    tableOption,
    dialogForm,
  },
  data() {
    return {
      api: {},
      loading: false,
      list: [],
      rawTable: {},
      timestep: new Date().getTime(),
      params: {},
      table: {},
      editForm: {},
      actions: [],
      pagination: null
    }
  },
  mounted() {
    const { config } = this.$route.query
    if (config === 'preview') {
      this.previewInit()
    } else {
      this.loadBiz()
    }
  },
  watch: {
    $route() {
      this.loadBiz()
    }
  },
  methods: {
    previewInit() {
      const { fields = [], tableConfig, actions, pagination, api, formConfig = {} } = JSON.parse(sessionStorage.getItem('previewData'))
      this.table = {
        ...tableConfig,
        fields,
        formConfig,
        actions: actions.filter(i => i.position === '1')
      }
      if (pagination) {
        this.pagination = pagination
        const { pageSize = 10 } = pagination
        this.params = { pageNo: 1, pageSize }
      }
      this.api = api
      this.actions = actions.filter(i => i.position === '2')
      this.$refs.filter.init(this.table)
      this.$refs.setting.init(this.table)
    },
    async loadBiz() {
      bus.on('menu-disable', true);
      Object.assign(this.$data, this.$options.data.call(this));
      await this.init()
      await this.query()
      bus.on('menu-disable', false);
    },
    async init() {
      this.loading = true
      const { config } = this.$route.query
      const configPath = `/config/${config}.json`
      try {
        const res = await axios.get(configPath);
        const {
          api = [],
          fields = [],
          actions = [],
          pagination,
          formConfig = {},
          tableConfig = {}
        } = res.data
        this.table = { ...tableConfig, fields, formConfig, actions: actions.filter(i => i.position === '1') }
        for (let i = 0; i < fields.length; i++) {
          const item = fields[i];
          if (typeof item.asyncOptions === 'object') {
            item.options = await request(item.asyncOptions)
          } else if (typeof item.asyncOptions === 'string') {
            item.options = await new Function('http', item.asyncOptions).bind(this)(http)
          }
        }
        if (pagination) {
          this.pagination = pagination
          const { pageSize = 10 } = pagination
          this.params = { pageNo: 1, pageSize }
        }
        this.api = api
        this.actions = actions.filter(i => i.position === '2')
        this.$refs.filter.init(this.table)
        this.$refs.setting.init(this.table)
      } catch (error) {
        console.log(error)
        this.$message.error(`配置文件${configPath}加载失败`)
      } finally {
        this.loading = false
      }
    },
    tableEvent(btn, data) {
      const { $index, column, row } = data
      new Function('data', 'index', 'column', btn.action).bind(this)(row, $index, column)
    },
    async onSubmit(data) {
      const { uniqueKey = 'id' } = this.$route.query
      if (this.form[uniqueKey]) {
        await this.update(data)
      } else {
        await this.insert(data)
      }
    },
    onQuery(data) {
      const { pageSize } = this.params
      this.params = { ...data, pageNo: 1, pageSize }
      this.query()
    },
    pageNoChange(pageNo) {
      console.log('xxxxxxxxxxxx')
      this.params.pageNo = pageNo
      this.query()
    },
    pageSizeChange(pageSize) {
      this.params.pageSize = pageSize
      this.query()
    },
    actionHandle(action) {
      new Function('data', action.action).bind(this)()
    },
    async update(data) {
      this.loading = true
      try {
        const res = await this.requestApi('update', data);
        console.log(res)
      } catch (error) {
        console.log(error)
      } finally {
        this.loading = false
        this.query()
      }
    },
    async insert(data) {
      this.loading = true
      try {
        const res = await this.requestApi('insert', data);
        console.log(res)
      } catch (error) {
        console.log(error)
      } finally {
        this.loading = false
        this.query()
      }
    },
    async query() {
      this.loading = true
      try {
        const res = await this.requestApi('query', this.params);
        this.list = res.data;
        if (this.pagination) {
          this.pagination.total = 100;
        }
      } catch (error) {
        console.log(error)
      } finally {
        this.loading = false
      }
    },
    async delete() {
      this.loading = true
      try {
        const res = await this.requestApi('delete', data);
        console.log(res)
      } catch (error) {
        console.log(error)
      } finally {
        this.loading = false
      }
    },
    async requestApi(key, data) {
      const api = this.api.find(i => i.name === key)
      if (api && api.url) {
        return request(api, data);
      } else {
        this.$message.error(`缺少${key}接口配置`)
        throw new Error(`缺少${key}接口配置`)
      }
    },
    handlerOptionChange(config) {
      this.table = config
      this.timestep = new Date().getTime()
    },
    filterFields(list) {
      if (!list) return []
    },
    colunmWidthChange(value, b, data) {
      this.table.fields = this.table.fields.map(field => {
        if (field.type === data.type && field.label === data.label && field.prop === data.property) {
          field.columnWidth = value
        }
        return field
      })
      this.$refs.setting.init(this.table)
    }
  },
}
</script>
<style lang="scss">
.table-btns .el-link {
  margin: 0 5px;

  &:last-child {
    margin-right: 0;
  }

  &:first-child {
    margin-left: 0;
  }
}

.common-biz-filter {
  .el-form-item {
    margin-left: 10px;

    &:first-child {
      margin-left: 0;
    }

    &:last-child {
      margin-left: 0;
    }
  }
}
</style>
<style scoped lang="scss">
.common-biz-filter {
  margin-bottom: 10px;
}

.common-biz-tool {
  display: flex;
  margin-bottom: 20px;
  align-items: center;
  justify-content: space-between;
}

.common-biz-pagnation {
  margin-top: 20px;
}
</style>